﻿using System;
using System.Windows.Controls;
using System.Windows.Data;
using SQLToolbox.View.Types;
using System.ComponentModel;
using SQLToolbox.Controller;
using SQLToolbox.Types;
using System.Windows;
using System.Windows.Media;
namespace SQLToolbox.View.UserControls
{
	/// <summary>
	/// Interaction logic for ucCompRes.xaml
	/// </summary>
	public partial class SchemaComparisonResultsViewer : UserControl, IComparisonToolbarTarget
	{

		ISchemaComparatorController controller;
		SchemaComaprison comparisonResults;

		public SchemaComparisonResultsViewer()
		{
			InitializeComponent();
		}
		public SchemaComparisonResultsViewer(ISchemaComparatorController controller)
		{
			InitializeComponent();
			this.controller = controller;
		}

		private void SetDatabases()
		{
			LDatabase.Text = string.Format("{0}.{1}", comparisonResults.Left.ServerName, comparisonResults.Left.DatabaseName);
			RDatabase.Text = string.Format("{0}.{1}", comparisonResults.Right.ServerName, comparisonResults.Right.DatabaseName);
			
		//	Databases.Text = string.Format("{0}.{1} -> {2}.{3}", comparisonResults.Left.ServerName, comparisonResults.Left.DatabaseName, comparisonResults.Right.ServerName, comparisonResults.Right.DatabaseName);
		}

		public void SetSource(SchemaComaprison crc)
		{
			comparisonResults = crc;
			SetListViewSource();
			SetDatabases();
		}

		private void SetListViewSource()
		{
			lv1.ItemsSource = null;
			lv1.SelectionChanged -= new SelectionChangedEventHandler(lv1_SelectionChanged);
			ICollectionView cvs = CollectionViewSource.GetDefaultView(comparisonResults);
			cvs.GroupDescriptions.Clear();
			cvs.GroupDescriptions.Add(new PropertyGroupDescription("Type"));
			cvs.SortDescriptions.Clear();
			cvs.SortDescriptions.Add(new SortDescription("Type", ListSortDirection.Ascending));
			cvs.SortDescriptions.Add(new SortDescription("Name", ListSortDirection.Ascending));
			lv1.ItemsSource = comparisonResults;
			lv1.SelectionChanged += new SelectionChangedEventHandler(lv1_SelectionChanged);
		}

		//public void ShowLog()
		//{
		//    lv1.Visibility = Visibility.Hidden | Visibility.Collapsed;
		//    sv.Visibility = Visibility.Visible;
		//}
		//public void HideLog()
		//{
		//    sv.Visibility = Visibility.Hidden | Visibility.Collapsed;
		//    lv1.Visibility = Visibility.Visible;
		//}

		//public void AddLogLine(string line)
		//{
		//    sv.AddText(line);
		//}

		public void SetStatus(string line)
		{
			status.Text = line;
		}

		public void ClearStatus()
		{
			status.Text = string.Empty;
		}

		private void lv1_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{

			if (e.AddedItems.Count >= 1 && e.AddedItems[0] is SchemaObjectComparison)
			{
				comparer.Show(((SchemaObjectComparison)e.AddedItems[0]).ScriptComparisonResult);
			}
			else
				comparer.Clear();
		}

		#region IComparisonToolbarImplementer Members

		public void Swap()
		{
			RedoComparison(comparisonResults.Right, comparisonResults.Left);
			var t = comparisonResults.Left;
			comparisonResults.Left = comparisonResults.Right;
			comparisonResults.Right = t;
			SetDatabases();
		}

		public void Refresh()
		{
			RedoComparison(comparisonResults.Left, comparisonResults.Right);
			SetDatabases();
		}

        /// <summary>
        /// Right is the source left is the target
        /// </summary>
        public void MatchLTR()
        {
            Match(comparisonResults,UpdateDirection.RightToLeft);
        }
        /// <summary>
        /// Left is the source right is the target
        /// </summary>
        public void MatchRTL()
        {
            Match(comparisonResults, UpdateDirection.LeftToRight);
        }
	
    

		#endregion
        private void RedoComparison(DBConnectionProperties a, DBConnectionProperties b)
        {
            if (controller != null && a != null && b != null)
            {
                controller.RedoComparison(a, b,
                    new Action<SchemaComaprison>(s =>
                    {
                        this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                                      new Action(() => { this.SetSource(s); }));
                    }));
            }
        }

        private void Match(SchemaComaprison cr, UpdateDirection direction)
        {
            if (controller != null && cr.Left != null && cr.Right != null)
            {
                controller.MatchSchemas(comparisonResults, direction,
                    new Action<SchemaComaprison>(s =>
                    {
                        this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
                                      new Action(() => { this.SetSource(s); }));
                    }));
            }
        }



		private void DoButtonClickAction(SchemaObjectComparison cr, UpdateDirection direction)
		{
			var index = lv1.SelectedIndex;
			controller.MatchObjects(comparisonResults, cr, direction,
						new Action<SchemaObjectComparison>(s =>
									{
										this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal,
													  new Action(() =>
													  {
														  var crc = lv1.ItemsSource as SchemaComaprison;
														  var i = crc.IndexOf(cr);
														  if (s == null)
															  crc.RemoveAt(i);
														  else
														  {
															  crc[i] = s;
															  lv1.SelectedIndex = index;
														  }
													  }));
									}));
		}



		private void GridItemLeftButton_Clicked(object sender, System.Windows.RoutedEventArgs e)
		{
			SchemaObjectComparison cr = GetRowOnWhichButonWasClicked(e.OriginalSource as DependencyObject);
			DoButtonClickAction(cr, UpdateDirection.RightToLeft);
		}


		private void GridItemRightButton_Clicked(object sender, System.Windows.RoutedEventArgs e)
		{
			SchemaObjectComparison cr = GetRowOnWhichButonWasClicked(e.OriginalSource as DependencyObject);
			DoButtonClickAction(cr, UpdateDirection.LeftToRight);
		}

		private SchemaObjectComparison GetRowOnWhichButonWasClicked(DependencyObject source)
		{
			ListViewItem lvi = GetAncestorByType(
				source, typeof(ListViewItem)) as ListViewItem;
			if (lvi != null)
			{
				lv1.SelectedIndex = lv1.ItemContainerGenerator.IndexFromContainer(lvi);
				return lvi.Content as SchemaObjectComparison;
			}
			return null;
		}

		public static DependencyObject GetAncestorByType(DependencyObject element, Type type)
		{
			if (element == null) return null;
			if (element.GetType() == type) return element;
			return GetAncestorByType(VisualTreeHelper.GetParent(element), type);
		}


	}



	public class UpdateActionVisibilityConverter : IValueConverter
	{
		#region IValueConverter Members

		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			if (((SchemaUpdateAction)value) == SchemaUpdateAction.Skip)
				return System.Windows.Visibility.Hidden;
			return System.Windows.Visibility.Visible;
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			throw new NotImplementedException();
		}

		#endregion
	}

	public class UpdateActionIconPathConverter : IValueConverter
	{
		#region IValueConverter Members

		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			if (parameter == null)
				return string.Empty;
			UpdateDirection ud = (UpdateDirection)parameter;
			switch ((SchemaUpdateAction)value)
			{
				case SchemaUpdateAction.Alter:
					if (ud == UpdateDirection.LeftToRight)
						return "../Resources/Right.ico";
					else
						return "../Resources/Left.ico";
				case SchemaUpdateAction.Create:
					if (ud == UpdateDirection.LeftToRight)
						return "../Resources/LeftDel.ico";
					else
						return "../Resources/RightDel.ico";
				case SchemaUpdateAction.Drop:
					if (ud == UpdateDirection.LeftToRight)
						return "../Resources/Right.ico";
					else
						return "../Resources/Left.ico";
				default:
					return string.Empty;
			}
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			throw new NotImplementedException();
		}

		#endregion
	}


	public class UpdateActionIconTooltipConverter : IValueConverter
	{
		#region IValueConverter Members

		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			if (parameter == null)
				return string.Empty;
			UpdateDirection ud = (UpdateDirection)parameter;
			switch ((SchemaUpdateAction)value)
			{
				case SchemaUpdateAction.Alter:
					if (ud == UpdateDirection.LeftToRight)
						return "Match to right side";
					else
						return "Match to left side";
				case SchemaUpdateAction.Create:
					if (ud == UpdateDirection.LeftToRight)
						return "Drop to match right side";
					else
						return "Drop to match left side";
				case SchemaUpdateAction.Drop:
					if (ud == UpdateDirection.LeftToRight)
						return "Create to match right side";
					else
						return "Create to match left side";
				default:
					return string.Empty;
			}
		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			throw new NotImplementedException();
		}

		#endregion
	}

	
	
	//statusToIconPathConverter

	public class ComparisonStatusIconPathConverter : IValueConverter
	{
		#region IValueConverter Members

		public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			switch ((ComparisonStatus)value)
			{
				case ComparisonStatus.Equal:
					return "../Resources/Equal.ico";
				case ComparisonStatus.Different:
					return "../Resources/Different.ico";
				case ComparisonStatus.New:
					return "../Resources/New.ico";
				case ComparisonStatus.Missing:
					return "../Resources/Missing.ico";
				default:
					break;
			}
			return null;

		}

		public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			throw new NotImplementedException();
		}

		#endregion
	}

}
